home *** CD-ROM | disk | FTP | other *** search
- #define LIBQBUILD_CORE
- #include "../include/libqbuild.h"
-
- int headclipnode; /* 4 */
- int firstface; /* 4 */
-
- int *planemapping;
-
- /*=========================================================================== */
-
- /*
- * ==================
- * FindFinalPlane
- *
- * Used to find plane index numbers for clip nodes read from child processes
- * ==================
- */
- int FindFinalPlane(__memBase, struct dplane_t *p)
- {
- int i;
- struct dplane_t *dplane;
-
- for (i = 0, dplane = bspMem->shared.quake1.dplanes; i < bspMem->shared.quake1.numplanes; i++, dplane++) {
- if (p->type != dplane->type)
- continue;
- if (p->dist != dplane->dist)
- continue;
- if (p->normal[0] != dplane->normal[0])
- continue;
- if (p->normal[1] != dplane->normal[1])
- continue;
- if (p->normal[2] != dplane->normal[2])
- continue;
- return i;
- }
-
- /* new plane */
- if (bspMem->shared.quake1.numplanes == bspMem->shared.quake1.max_numplanes)
- ExpandClusters(bspMem, LUMP_PLANES);
- dplane = &bspMem->shared.quake1.dplanes[bspMem->shared.quake1.numplanes];
- *dplane = *p;
- bspMem->shared.quake1.numplanes++;
-
- return bspMem->shared.quake1.numplanes - 1;
- }
-
- void WriteNodePlanes_r(__memBase, register struct node *node)
- {
- struct plane *plane;
- struct dplane_t *dplane;
-
- if (node->planenum == -1)
- return;
- if (planemapping[node->planenum] == -1) { /* a new plane */
-
- planemapping[node->planenum] = bspMem->shared.quake1.numplanes;
-
- if (bspMem->shared.quake1.numplanes == bspMem->shared.quake1.max_numplanes)
- ExpandClusters(bspMem, LUMP_PLANES);
- #ifdef EXHAUSIVE_CHECK
- if (node->planenum >= bspMem->numbrushplanes || node->planenum < 0)
- Error("looking for nonexisting plane %d\n", node->planenum);
- #endif
- plane = &bspMem->brushplanes[node->planenum];
- dplane = &bspMem->shared.quake1.dplanes[bspMem->shared.quake1.numplanes];
- dplane->normal[0] = plane->normal[0];
- dplane->normal[1] = plane->normal[1];
- dplane->normal[2] = plane->normal[2];
- dplane->dist = plane->dist;
- dplane->type = plane->type;
-
- bspMem->shared.quake1.numplanes++;
- }
-
- node->outputplanenum = planemapping[node->planenum];
-
- WriteNodePlanes_r(bspMem, node->children[0]);
- WriteNodePlanes_r(bspMem, node->children[1]);
- }
-
- /*
- * ==================
- * WriteNodePlanes
- *
- * ==================
- */
- void WriteNodePlanes(__memBase, struct node *nodes)
- {
- if (!(planemapping = (int *)tmalloc(sizeof(int) * bspMem->numbrushplanes)))
- Error(failed_memoryunsize, "planemapping");
- memset(planemapping, -1, sizeof(int) * bspMem->numbrushplanes);
-
- WriteNodePlanes_r(bspMem, nodes);
- tfree(planemapping);
- }
-
- /*=========================================================================== */
-
- /*
- * ==================
- * WriteClipNodes_r
- *
- * ==================
- */
- int WriteClipNodes_r(__memBase, register struct node *node)
- {
- int c;
- short int i;
- struct dclipnode_t *cn;
- int num;
-
- /* FIXME: tfree more stuff? */
- if (node->planenum == -1) {
- num = node->contents;
- tfree(node);
- return num;
- }
-
- if (bspMem->shared.quake1.numclipnodes == bspMem->shared.quake1.max_numclipnodes)
- ExpandClusters(bspMem, LUMP_CLIPNODES);
- /* emit a clipnode */
- c = bspMem->shared.quake1.numclipnodes;
- cn = &bspMem->shared.quake1.dclipnodes[c];
- bspMem->shared.quake1.numclipnodes++;
-
- cn->planenum = node->outputplanenum;
- for (i = 0; i < 2; i++)
- cn->children[i] = WriteClipNodes_r(bspMem, node->children[i]);
-
- tfree(node);
- return c;
- }
-
- /*
- * ==================
- * WriteClipNodes
- *
- * Called after the clipping hull is completed. Generates a disk format
- * representation and frees the original memory.
- * ==================
- */
- void WriteClipNodes(__memBase, struct node *nodes)
- {
- headclipnode = bspMem->shared.quake1.numclipnodes;
- WriteClipNodes_r(bspMem, nodes);
- }
-
- /*=========================================================================== */
-
- /*
- * ==================
- * WriteLeaf
- * ==================
- */
- void WriteLeaf(__memBase, register struct node *node)
- {
- struct visfacet **fp, *f;
- struct dleaf_t *leaf_p;
-
- /* emit a leaf */
- if (bspMem->shared.quake1.numleafs == bspMem->shared.quake1.max_numleafs)
- ExpandClusters(bspMem, LUMP_LEAFS);
- leaf_p = &bspMem->shared.quake1.dleafs[bspMem->shared.quake1.numleafs];
- bspMem->shared.quake1.numleafs++;
-
- leaf_p->contents = node->contents;
-
- /* write bounding box info */
- VectorCopy(node->mins, leaf_p->mins);
- VectorCopy(node->maxs, leaf_p->maxs);
-
- leaf_p->visofs = -1; /* no vis info yet */
-
- /* write the marksurfaces */
- leaf_p->firstmarksurface = bspMem->shared.quake1.nummarksurfaces;
-
- for (fp = node->markfaces; *fp; fp++) {
- /* emit a marksurface */
- f = *fp;
- do {
- if (bspMem->shared.quake1.nummarksurfaces == bspMem->shared.quake1.max_nummarksurfaces)
- ExpandClusters(bspMem, LUMP_MARKSURFACES);
- bspMem->shared.quake1.dmarksurfaces[bspMem->shared.quake1.nummarksurfaces] = f->outputnumber;
- bspMem->shared.quake1.nummarksurfaces++;
- f = f->original; /* grab tjunction split faces */
- } while (f);
- }
-
- leaf_p->nummarksurfaces = bspMem->shared.quake1.nummarksurfaces - leaf_p->firstmarksurface;
- }
-
- /*
- * ==================
- * WriteDrawNodes_r
- * ==================
- */
- void WriteDrawNodes_r(__memBase, register struct node *node)
- {
- struct dnode_t *n;
- short int i;
-
- /* emit a node */
- if (bspMem->shared.quake1.numnodes == bspMem->shared.quake1.max_numnodes)
- ExpandClusters(bspMem, LUMP_NODES);
- n = &bspMem->shared.quake1.dnodes[bspMem->shared.quake1.numnodes];
- bspMem->shared.quake1.numnodes++;
-
- VectorCopy(node->mins, n->mins);
- VectorCopy(node->maxs, n->maxs);
-
- n->planenum = node->outputplanenum;
- n->firstface = node->firstface;
- n->numfaces = node->numfaces;
-
- /* recursively output the other nodes */
- for (i = 0; i < 2; i++) {
- if (node->children[i]->planenum == -1) {
- if (node->children[i]->contents == CONTENTS_SOLID)
- n->children[i] = -1;
- else {
- n->children[i] = -(bspMem->shared.quake1.numleafs + 1);
- WriteLeaf(bspMem, node->children[i]);
- }
- }
- else {
- n->children[i] = bspMem->shared.quake1.numnodes;
- WriteDrawNodes_r(bspMem, node->children[i]);
- }
- }
- }
-
- /*
- * ==================
- * WriteDrawNodes
- * ==================
- */
- void WriteDrawNodes(__memBase, struct node *headnode)
- {
- short int i;
- int start;
- struct dmodel_t *bm;
-
- #if 0
- if (headnode->contents < 0)
- Error("FinishBSPModel: empty model");
- #endif
-
- /* emit a model */
- if (bspMem->shared.quake1.nummodels == bspMem->shared.quake1.max_nummodels)
- ExpandClusters(bspMem, LUMP_MODELS);
- bm = &bspMem->shared.quake1.dmodels[bspMem->shared.quake1.nummodels];
- bspMem->shared.quake1.nummodels++;
-
- bm->headnode[0] = bspMem->shared.quake1.numnodes;
- bm->firstface = firstface;
- bm->numfaces = bspMem->shared.quake1.numfaces - firstface;
- firstface = bspMem->shared.quake1.numfaces;
-
- start = bspMem->shared.quake1.numleafs;
-
- if (headnode->contents < 0)
- WriteLeaf(bspMem, headnode);
- else
- WriteDrawNodes_r(bspMem, headnode);
- bm->visleafs = bspMem->shared.quake1.numleafs - start;
-
- for (i = 0; i < 3; i++) {
- bm->mins[i] = headnode->mins[i] + SIDESPACE + 1; /* remove the padding */
- bm->maxs[i] = headnode->maxs[i] - SIDESPACE - 1;
- }
- /* FIXME: are all the children decendant of padded nodes? */
- }
-
- /*
- * ==================
- * BumpModel
- *
- * Used by the clipping hull processes that only need to store headclipnode
- * ==================
- */
- void BumpModel(__memBase, int hullnum)
- {
- struct dmodel_t *bm;
-
- /* emit a model */
- if (bspMem->shared.quake1.nummodels == bspMem->shared.quake1.max_nummodels)
- ExpandClusters(bspMem, LUMP_MODELS);
- bm = &bspMem->shared.quake1.dmodels[bspMem->shared.quake1.nummodels];
- bspMem->shared.quake1.nummodels++;
-
- bm->headnode[hullnum] = headclipnode;
- }
-
- /*============================================================================= */
-
- #define MAX_MULTIPLE 32
-
- /*
- * ==================
- * WriteMiptex
- * ==================
- */
- void WriteMiptex(__memBase)
- {
- if (!(bspMem->bspOptions & QBSP_NOTEXTURES)) {
- struct wadheader Header[MAX_MULTIPLE + 1];
- struct wadentry *allEntries[MAX_MULTIPLE + 1];
- char *wadPath[MAX_MULTIPLE + 1];
- HANDLE wadFile[MAX_MULTIPLE + 1];
- int wadAvail = 0;
-
- char *dirPath[MAX_MULTIPLE + 1];
- DIR *dirDir[MAX_MULTIPLE + 1];
- int dirAvail = 0;
-
- /* TODO: multiple wadFiles */
- if (bspMem->mapentities) {
- wadPath[0] = ValueForKey(&bspMem->mapentities[0], "_wad");
- if (!wadPath[0] || !wadPath[0][0])
- wadPath[0] = ValueForKey(&bspMem->mapentities[0], "wad");
- }
- else
- wadPath[0] = 0;
- if (!wadPath[0] || !wadPath[0][0])
- wadPath[0] = getenv("QUAKE_WADFILE");
-
- if (wadPath[0] && wadPath[0][0]) { /* do only if there exists really a wad */
- for (wadAvail = 0; wadAvail < MAX_MULTIPLE;) {
- char *hit;
-
- if ((hit = (char *)__strchr(wadPath[wadAvail], ';'))) { /* cut off next entry */
- *hit = ' ';
- while ((hit[-1] == ' ') || (hit[-1] == '\t')) /* delete whitespace */
- hit--;
- *hit++ = '\0';
- while ((*hit == ' ') || (*hit == '\t')) /* delete whitespace */
- hit++;
- }
- #ifdef DEBUG
- printf("wadPath %2d: \"%s\"\n", wadAvail, wadPath[wadAvail]);
- #endif
-
- if ((wadPath[wadAvail][0]) && (wadFile[wadAvail] = __open(wadPath[wadAvail], H_READ_BINARY)) > 0) {
- if (CheckWAD2(wadFile[wadAvail], &Header[wadAvail], FALSE)) {
- FindWAD2(wadFile[wadAvail], 0, &Header[wadAvail], &allEntries[wadAvail], 0);
- wadAvail++;
- }
- else {
- __close(wadFile[wadAvail]);
- eprintf("file \"%s\" not a wad\n", wadPath[wadAvail]);
- }
- }
- else
- eprintf(failed_fileopen, wadPath[wadAvail]);
-
- if (!hit) /* break if nothing more found */
- break;
- else
- wadPath[wadAvail] = hit; /* register next entry */
- }
- }
-
- /* TODO: multiple dirDirs */
- if (bspMem->mapentities) {
- dirPath[0] = ValueForKey(&bspMem->mapentities[0], "_dir");
- if (!dirPath[0] || !dirPath[0][0])
- dirPath[0] = ValueForKey(&bspMem->mapentities[0], "dir");
- }
- else
- dirPath[0] = 0;
- if (!dirPath[0] || !dirPath[0][0])
- dirPath[0] = getenv("QUAKE_WADDIR");
- if (!dirPath[0] || !dirPath[0][0])
- dirPath[0] = "\0";
-
- for (dirAvail = 0; dirAvail < MAX_MULTIPLE;) { /* do ever, 'cause we have ever a valid dir (current dir) */
- char *hit;
-
- if ((hit = (char *)__strchr(dirPath[dirAvail], ';'))) { /* cut off next entry */
- *hit = ' ';
- while ((hit[-1] == ' ') || (hit[-1] == '\t')) /* delete whitespace */
- hit--;
- *hit++ = '\0';
- while ((*hit == ' ') || (*hit == '\t')) /* delete whitespace */
- hit++;
- }
- #ifdef DEBUG
- printf("dirPath %2d: \"%s\"\n", dirAvail, dirPath[dirAvail]);
- #endif
-
- if ((dirDir[dirAvail] = opendir(dirPath[dirAvail])))
- dirAvail++; /* skip unavailable entries */
- else
- eprintf("dir \"%s\" is not a dir, or does not exists\n", dirPath[dirAvail]);
-
- if (!hit) /* break if nothing more found */
- break;
- else
- dirPath[dirAvail] = hit; /* register next entry */
- }
- #ifdef DEBUG
- printf("wads %2d, dirs %2d\n", wadAvail, dirAvail);
- #endif
-
- if ((wadAvail || dirAvail) && bspMem->nummaptexstrings) {
- int i;
- unsigned char *mipFlow;
- struct dmiptexlump_t *mipBlock;
- int texstrings = bspMem->nummaptexstrings;
-
- if (!bspMem->shared.quake1.dtexdata)
- AllocClusters(bspMem, LUMP_TEXTURES);
- mipBlock = (struct dmiptexlump_t *)bspMem->shared.quake1.dtexdata;
- mipFlow = (unsigned char *)&mipBlock->dataofs[bspMem->nummaptexstrings];
- mipBlock->nummiptex = bspMem->nummaptexstrings;
- bspMem->shared.quake1.texdatasize = mipFlow - bspMem->shared.quake1.dtexdata;
-
- for (i = 0; i < texstrings; i++) {
- struct rawdata *inPut;
-
- void GetInput(char *inName) {
- int j;
- struct wadentry *Entry;
-
- inPut = 0;
-
- /* first search in wadFiles */
- for (j = 0; j < wadAvail; j++)
- if ((Entry = SearchWAD2(inName, &Header[j], allEntries[j], TYPE_MIPMAP)))
- inPut = GetWAD2Raw(wadFile[j], Entry);
-
- /* if nothing found, search in dirDirs */
- for (j = 0; (j < dirAvail) && !(inPut); j++) {
- struct dirent *dirEnt = 0;
-
- while ((dirEnt = readdir(dirDir[j]))) {
- #ifdef DEBUG
- printf("dirname: %s wadname: %s\n", dirEnt->d_name, inName);
- #endif
- if (!__strncasecmp(dirEnt->d_name, inName, strlen(inName))) /* metal1 matches metal10* */
- if (dirEnt->d_name[strlen(inName)] == '.') /* metal1 matches metal1.* */
- break;
- } if (dirEnt) {
- char *fileExt = GetExt(dirEnt->d_name);
- FILE *inFile;
- struct palpic *inPic = 0;
- char *fileName;
-
- if ((fileName = (char *)tmalloc(NAMELEN_PATH + 1))) {
- __strncpy(fileName, dirPath[j], NAMELEN_PATH);
- __strncat(fileName, "/", NAMELEN_PATH);
- __strncat(fileName, dirEnt->d_name, NAMELEN_PATH);
-
- if ((inFile = __fopen(fileName, F_READ_BINARY))) {
- if (!__strcmp(fileExt, "mip"))
- inPut = GetRaw(fileno(inFile), inName, 0);
- else if (!__strcmp(fileExt, "lmp"))
- inPic = GetLMP(fileno(inFile), inName);
- else {
- short int alignX = 16, alignY = 16;
-
- if (fileName[0] == WARP_MIPMAP)
- alignX = alignY = WARP_X;
- else if (!__strncasecmp(fileName, SKY_MIPMAP, 3)) {
- alignX = -(SKY_X);
- alignY = -(SKY_Y);
- }
- inPic = GetImage(inFile, inName, alignX, alignY);
- }
-
- if (inPic) {
- if ((inPut = rmalloc(MIP_MULT(inPic->width * inPic->height) + sizeof(struct mipmap), inName)))
- PasteMipMap((struct mipmap *)inPut->rawdata, inPic);
-
- pfree(inPic);
- }
- else
- eprintf("unknown fileformat %s\n", fileName);
-
- __fclose(inFile);
- }
- else
- eprintf(failed_fileopen, fileName);
-
- tfree(fileName);
- }
- }
-
- rewinddir(dirDir[j]);
- }
- }
-
- void PutInput(char *inName) {
- if (inPut) {
- mipBlock->dataofs[i] = mipFlow - (unsigned char *)mipBlock;
- mprintf(" - load texture %s\n", inPut->name);
-
- if ((bspMem->shared.quake1.texdatasize + inPut->size) >= bspMem->shared.quake1.max_texdatasize) {
- ExpandClusters(bspMem, LUMP_TEXTURES);
- mipBlock = (struct dmiptexlump_t *)bspMem->shared.quake1.dtexdata;
- mipFlow = bspMem->shared.quake1.dtexdata + bspMem->shared.quake1.texdatasize;
- } bspMem->shared.quake1.texdatasize += inPut->size;
-
- memcpy(mipFlow, inPut->rawdata, inPut->size);
- mipFlow += inPut->size;
- rfree(inPut);
- }
- else {
- mipBlock->dataofs[i] = -1;
- eprintf("texture %s not found!\n", inName);
- }
- }
-
- if (bspMem->maptexstrings[i][0] == '+') {
- int j;
- char name[20];
-
- __strcpy(name, bspMem->maptexstrings[i]);
-
- for (j = 0; j < 20; j++) {
- if (j < 10)
- name[1] = '0' + j;
- else
- name[1] = 'A' + j - 10; /* alternate animation */
-
- GetInput(name); /* see if this name exists in the wadfile */
- PutInput(name); /* put only if it exists */
- /*FindMiptex(bspMem, name); // add to the miptex list, if somebody after us needs it */
- }
- }
- else {
- GetInput(bspMem->maptexstrings[i]);
- PutInput(bspMem->maptexstrings[i]);
- }
- }
-
- for (i = 0; i < wadAvail; i++)
- __close(wadFile[i]);
- for (i = 0; i < dirAvail; i++)
- closedir(dirDir[i]);
- }
- else
- eprintf(failed_fileopen, "wadfile(s) or dir(s)");
- }
- }
-
- /*=========================================================================== */
-
- /*
- * ==================
- * BeginBSPFile
- * ==================
- */
- void BeginBSPFile(__memBase)
- {
- bspMem->availHeaders = 0;
- AllocClusters(bspMem, ((ALL_QUAKE1_LUMPS) | (ALL_MAPS)) & (~((LUMP_LIGHTING) | (LUMP_VISIBILITY))));
-
- /* edge 0 is not used, because 0 can't be negated */
- bspMem->shared.quake1.numedges = 1;
-
- /* leaf 0 is common solid with no faces */
- bspMem->shared.quake1.numleafs = 1;
- bspMem->shared.quake1.dleafs[0].contents = CONTENTS_SOLID;
-
- firstface = 0;
- }
-
- /*
- * ==================
- * FinishBSPFile
- * ==================
- */
- void FinishBSPFile(__memBase, HANDLE bspFile)
- {
- mprintf("----- FinishBSPFile -----\n");
-
- WriteMiptex(bspMem);
- WriteBSP(bspFile, bspMem, BSP_VERSION_Q1);
- PrintClusters(bspMem, 0, TRUE);
- }
-